#ifndef __MP_FILTER__
#define __MP_FILTER__

#include "mpboost.h"

namespace xm
{
	typedef std::set<FMTID>		fmtidset_t;

	struct booster_t
	{
		BloomFilter6		bloomflt;
		ShiftTableS2		shifttab;
	};

	class mp_base_filter
	{
	public:

		iptr<IKMDRTable>	_curr_table;

		booster_t			_booster;

		cblob_t				_curr_data;

		fmtidset_t			_care_fmts;

		inline void care_format( FMTID fmt )
		{
			_care_fmts.insert( fmt );
		}

		inline HRESULT update( IKMDRTable * tablep )
		{
			if( !tablep )
			{
				clear();
				return S_OK;
			}

			if( tablep->IsSameTable(_curr_table) )
				return S_OK;

			clear();
			if( FAILED( build_index( tablep, _curr_data ) ) ) 
				clear();

			_curr_table = tablep;

			return S_OK;
		}
		inline BloomFilter6& bloom_filter()
		{
			return _booster.bloomflt;
		}
		inline ShiftTableS2& shift_table()
		{
			return _booster.shifttab;
		}
		inline bool_t is_hit( LPCSTR cpData, FMTID uFmtId )
		{
			return bloom_filter().maybe_hit( cpData, uFmtId);
		}
		inline size_t skip_bytes( LPCSTR cpData )
		{
			return shift_table().get_shift( ShiftTableS2::hashv(cpData+PREFIX_LENGTH-1) );
		}
		virtual VOID clear()
		{
			bloom_filter().clear();
			shift_table().clear();
			_curr_table.dispose();
			_care_fmts.clear();
			_curr_data.Data = 0;
			_curr_data.Length = 0;
		}
		inline bool is_fmt_cared( FMTID fmtid )
		{
			return _care_fmts.find(fmtid) != _care_fmts.end();
		}
		virtual HRESULT build_index( IKMDRTable * lpTable, cblob_t& br_data ) = 0;
	};
};



#endif